package com.gframework.core.middleware;

import java.io.IOException;

import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HttpContext;

/**
 * 一个可以自定义redirect拦截操作的HttpClient包装对象
 * 
 * @since 1.0.0
 * @author Ghwolf
 */
@SuppressWarnings("deprecation")
public class CustomRedirectHttpClientWrapper extends CloseableHttpClient {

	/**
	 * 包装对象
	 */
	private final CloseableHttpClient client;
	/**
	 * 重定向策略和拦截操作对象
	 */
	private final CustomRedirectStrategy reditrectStrategy;

	CustomRedirectHttpClientWrapper(CloseableHttpClient client, CustomRedirectStrategy reditrectStrategy) {
		this.client = client;
		this.reditrectStrategy = reditrectStrategy;
	}

	@Override
	public void close() throws IOException {
		client.close();
	}

	/**
	 * 可以拦截重定向操作的操作。
	 * 
	 * @see #execute(HttpHost, HttpRequest, HttpContext)
	 */
	public CloseableHttpResponse execute(HttpHost target, HttpRequest request, HttpContext context,
			HttpRedirectInterceptor interceptor) throws IOException, ClientProtocolException {
		try {
			this.reditrectStrategy.set(interceptor);
			return client.execute(target, request, context);
		} finally {
			this.reditrectStrategy.clear();
		}
	}

	/**
	 * 可以拦截重定向操作的操作。
	 * 
	 * @see #execute(HttpUriRequest, HttpContext)
	 */
	public CloseableHttpResponse execute(HttpUriRequest request, HttpContext context,
			HttpRedirectInterceptor interceptor) throws IOException, ClientProtocolException {
		try {
			this.reditrectStrategy.set(interceptor);
			return client.execute(request, context);
		} finally {
			this.reditrectStrategy.clear();
		}
	}

	/**
	 * 可以拦截重定向操作的操作。
	 * 
	 * @see #execute(HttpUriRequest)
	 */
	public CloseableHttpResponse execute(HttpUriRequest request, HttpRedirectInterceptor interceptor)
			throws IOException, ClientProtocolException {
		try {
			this.reditrectStrategy.set(interceptor);
			return client.execute(request);
		} finally {
			this.reditrectStrategy.clear();
		}
	}

	/**
	 * 可以拦截重定向操作的操作。
	 * 
	 * @see #execute(HttpHost, HttpRequest)
	 */
	public CloseableHttpResponse execute(HttpHost target, HttpRequest request, HttpRedirectInterceptor interceptor)
			throws IOException, ClientProtocolException {
		try {
			this.reditrectStrategy.set(interceptor);
			return client.execute(target, request);
		} finally {
			this.reditrectStrategy.clear();
		}
	}

	/**
	 * 可以拦截重定向操作的操作。
	 * 
	 * @see #execute(HttpUriRequest, ResponseHandler)
	 */
	public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler,
			HttpRedirectInterceptor interceptor) throws IOException, ClientProtocolException {
		try {
			this.reditrectStrategy.set(interceptor);
			return client.execute(request, responseHandler);
		} finally {
			this.reditrectStrategy.clear();
		}
	}

	/**
	 * 可以拦截重定向操作的操作。
	 * 
	 * @see #execute(HttpUriRequest, ResponseHandler, HttpContext)
	 */
	public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context,
			HttpRedirectInterceptor interceptor) throws IOException, ClientProtocolException {
		try {
			this.reditrectStrategy.set(interceptor);
			return client.execute(request, responseHandler, context);
		} finally {
			this.reditrectStrategy.clear();
		}
	}

	/**
	 * 可以拦截重定向操作的操作。
	 * 
	 * @see #execute(HttpHost, HttpRequest, ResponseHandler)
	 */
	public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler,
			HttpRedirectInterceptor interceptor) throws IOException, ClientProtocolException {
		try {
			this.reditrectStrategy.set(interceptor);
			return client.execute(target, request, responseHandler);
		} finally {
			this.reditrectStrategy.clear();
		}
	}

	/**
	 * 可以拦截重定向操作的操作。
	 * 
	 * @see #execute(HttpHost, HttpRequest, ResponseHandler, HttpContext)
	 */
	public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler,
			HttpContext context, HttpRedirectInterceptor interceptor) throws IOException, ClientProtocolException {
		try {
			this.reditrectStrategy.set(interceptor);
			return client.execute(target, request, responseHandler, context);
		} finally {
			this.reditrectStrategy.clear();
		}
	}

	/**
	 * {@literal}
	 * 
	 * @see #execute(HttpHost, HttpRequest, HttpContext,
	 *      HttpRedirectInterceptor)
	 */
	@Override
	public CloseableHttpResponse execute(HttpHost target, HttpRequest request, HttpContext context)
			throws IOException, ClientProtocolException {
		return client.execute(target, request, context);
	}

	/**
	 * {@literal}
	 * 
	 * @see #execute(HttpUriRequest, HttpContext,
	 *      HttpRedirectInterceptor)
	 */
	@Override
	public CloseableHttpResponse execute(HttpUriRequest request, HttpContext context)
			throws IOException, ClientProtocolException {
		return client.execute(request, context);
	}

	/**
	 * {@literal}
	 * 
	 * @see #execute(HttpUriRequest, HttpRedirectInterceptor)
	 */
	@Override
	public CloseableHttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException {
		return client.execute(request);
	}

	/**
	 * {@literal}
	 * 
	 * @see #execute(HttpHost, HttpRequest, HttpRedirectInterceptor)
	 */
	@Override
	public CloseableHttpResponse execute(HttpHost target, HttpRequest request)
			throws IOException, ClientProtocolException {
		return client.execute(target, request);
	}

	/**
	 * {@literal}
	 * 
	 * @see #execute(HttpUriRequest, ResponseHandler,
	 *      HttpRedirectInterceptor)
	 */
	@Override
	public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler)
			throws IOException, ClientProtocolException {
		return client.execute(request, responseHandler);
	}

	/**
	 * {@literal}
	 * 
	 * @see #execute(HttpUriRequest, ResponseHandler, HttpContext,
	 *      HttpRedirectInterceptor)
	 */
	@Override
	public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context)
			throws IOException, ClientProtocolException {
		return client.execute(request, responseHandler, context);
	}

	/**
	 * {@literal}
	 * 
	 * @see #execute(HttpHost, HttpRequest, ResponseHandler,
	 *      HttpRedirectInterceptor)
	 */
	@Override
	public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler)
			throws IOException, ClientProtocolException {
		return client.execute(target, request, responseHandler);
	}

	/**
	 * {@literal}
	 * 
	 * @see #execute(HttpHost, HttpRequest, ResponseHandler, HttpContext,
	 *      HttpRedirectInterceptor)
	 */
	@Override
	public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler,
			HttpContext context) throws IOException, ClientProtocolException {
		return client.execute(target, request, responseHandler, context);
	}

	@Override
	public String toString() {
		return client.toString();
	}

	@Override
	public HttpParams getParams() {
		return client.getParams();
	}

	@Override
	public ClientConnectionManager getConnectionManager() {
		return client.getConnectionManager();
	}

	@Override
	protected CloseableHttpResponse doExecute(HttpHost target, HttpRequest request, HttpContext context)
			throws IOException, ClientProtocolException {
		throw new UnsupportedOperationException();
	}

}
